iT邦幫忙

2024 iThome 鐵人賽

DAY 9
1
DevOps

菜逼八用Github Actions系列 第 9

Day 09 - Github Actions的表達式 & function

  • 分享至 

  • xImage
  •  

目錄

摘要

在上一篇我們學到如何設置、使用secret,以及使用secret的時機

在這篇我們會來了解一下表達式跟function

表達式是什麼

表達式是很常用的功能,不管是取得變數值、context值,還是做條件判斷時都會用到

除了表達式以外Github Actions還提供了一系列的function、運算子(用法和大多數程式語言一樣,故不介紹),可以跟表達式一起用

# 是不是很眼熟?其實我們曾在context篇見過它
${{ <expression> }}

雖然常常看到表達式被${{}}包起來,但如果是用在if:時,則可以省略${{}},因為Github Actions會自動把if的條件當作表達式,但如果表達式的開頭有!,就一定要用\${{}}包住

if: steps.foo.outputs.bar

# 相當於
if: ${{github.steps.foo.outputs.bar}}

但是需要注意並不是所有的context省略與否都一樣

if: env.foo

# 不等於,這取不到變數值
if: ${{github.env.foo}}

function

假設有一個mono repo,它裡面2個workspace,分別為foo跟bar

如果是foo的PR那標題以[foo]開頭,bar則是[bar],後面接PR的類型(ex: feat、fix、refactor)

PR標題的格式則是[workspace name][PR type] description

  • contains

    • 檢查字串是否包含另一個子字串,或者array是否包含某個元素
    • 檢查PR標題是否包含[fix]
      if: contains(github.event.pull_request.title, '[fix]')
      
  • startsWith & endsWith

    • 檢查字串是否已某子字串開頭/結尾
    • 檢查PR開頭是不是[foo]
      if: startsWith(github.event.pull_request.title, '[foo]')
      
  • format

    • 根據傳入的pattern,把複數個字串組裝起來
    • format('Good {0} {1} {2}', 'morning', '!', 'Tempura')
      
  • join

    • 跟JS的.join()用法一樣,會將複數個元素用傳入的元素用separator串起來
    • join(['Good', 'morning'], ' ')
      
  • toJSON & fromJSON

    • 類似JS的json.stringify()、JSON.parse(),但是只能處理context物件(e.g.:env, steps, needs),無法一般處理物件
    env:
      # 只能宣告string、number、boolean
      # 記得要跳脫,或者最外層改用單引號,不然會報錯
      - str1: "{\"name\":\"Tempura\"}"
      - arrStr1: "[\"3\", \"4\"]"
    
    run: |
      echo ${{fromJSON(env.str1)}}
    
    # 試圖直接傳JSON字串會報錯 Unexpected symbol: '"{\"name\":\"Tempura\"}"'
    echo ${{fromJSON("{\"name\":\"Tempura\"}")}}
    
    # 試圖直接傳入object會報錯 Unexpected symbol: '{name:'
    echo ${{toJSON({name:"Tempura"})}}
    
    # 無法處理object會報錯
    echo ${{toJSON(fromJSON(env.str1))}}
    
  • hashFiles

    • 檢查傳入的檔案路徑是否正確
    • 檢查workspace內有無package.json.lock、output.css(Tailwind產生的css檔)
      if: hashFiles('**/package.json.lock', '**/src/styles/output.css')
      run: echo 'You should not push package.json.lock to remote. Add it to .gitignore'
      ```- 
      
  • success & failure

    • 判斷前一個step的結果,如果符合使用的function描述的狀態就繼續跑下一個step
    • if: ${{ success() }}
      
  • always

    • 讓step不論是否被取消與否,永遠都繼續執行
    • 官方並不建議隨意使用這個function,因為有些step出錯就是有critical failure,不該繼續執行下個step
    • 假設希望某個workflow壞掉時,希望在slack通知開發者去修理
      if: ${{ always() }}
      run: #送訊息給開發者說workflow壞掉了
      
  • cancelled

    • 無腦取消step執行
    • if: ${{ cancelled() }}
      

三元運算子

如果你想要根據條件賦予某個變數值,那比起寫兩個if條件相方的step,三元運算子確實是好選擇

可惜GitHub Actions並不支援三元運算子,但是有提供替代方案

格式是條件 && true時的return value || false時的return value

env:
  fruit: ${{ github.event.inputs.selectedFruit == 'apple' && 'apple' || 'banana' }}

Object filters

Object filters 是 GitHub Actions 提供的用來篩選object、array中元素的功能

- name: print name of fruits
  env: |
    fruits: [
      { name: 'apple' },
      { name: 'orange' },
      { name: 'peach' }
    ]

  run: echo $fruits.*.name
  # [ 'apple', 'orange', 'peach' ]
- name: print name of pets
  env: |
    pets: {
      cat: {
        black: ['Luna'],
        ginger: ['Oliver']
      },
      dog: {
        yellow: ['Milo'],
        black: ['Buddy']
      }
    }
  
  run: echo $pets.*.black
  # [
  #   ['Luna'],
  #   ['Buddy']
  # ]

上一篇
Day 08 - 儲存敏感資訊的secret
下一篇
Day 10 - 觸發workflow
系列文
菜逼八用Github Actions30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言